flask-login扩展进行会话管理
撰写时间: 2019-12-16 总共: 2730 字 转载请注明: BY-SA 4.0(除特别声明或转载文章外)
用户会话管理
Flask-Login
这个扩展提供了日常的登入、登出、记住会话的操作。
安装
pip install Flask-Login
使用
配置
创建一个登录管理器LoginManager
from flask import Flask
from flask_login import LoginManager
from config import config
app = Flask(__name__)
#添加配置信息
app.config.from_object(config.get('production'))
# 登录模块初始化
login = LoginManager(app)
# 登录限制,不通过时跳转到登录视图
login.login_view = 'main.login'
# 自定义未登录提示信息
login.login_manager = u'请先登录'
必要条件
from flask_login import current_user
from App import app,login
from App import app,login
from .models import db,User
# 从session里读取用户信息
# 接受一个Unicode ID作为参数
@login.user_loader
def load_user(id):
return User.query.get(int(id))
# 请求前的钩子
@app.before_request
def before_request():
g.user = current_user
if g.user.is_authenticated:
g.user.last_seen = datetime.now()
db.session.add(g.user)
db.session.commit()
而我们的用户表类,需要实现如下属性和方法,可以继承UserMixin
它提供了默认的设置。
is_authenticated
is_active
is_anonymous
get_id()
通常用户的密码是不明文存储的,我们通过hash方法简单实现密码的散列存储。
from . import db
from werkzeug.security import generate_password_hash,check_password_hash
from flask_login import UserMixin
class User(UserMixin,db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(64),index=True,unique=True)
email = db.Column(db.String(120),index=True,unique=True)
password_hash = db.Column(db.String(128))
last_seen = db.Column(db.DateTime)
avatar = db.Column(db.String(256))
posts = db.relationship('Post',backref='post_user',lazy='dynamic')
comments = db.relationship('Comment',backref='comment_user',lazy='dynamic')
articles = db.relationship('Article',backref='article_user',lazy='dynamic')
# 通过验证
def is_authenticated(self):
return True
# 已激活
def is_active(self):
return True
# 匿名用户
def is_anonymous(self):
return False
# 获取user id
def get_id(self):
return self.id
def set_password(self,password):
self.password_hash = generate_password_hash(password)
def check_password(self,password):
return check_password_hash(self.password_hash,password)
def __repr__(self):
return f'user:{self.user_name}'
登录的视图实现
@main.route('/login',methods=['GET','POST'])
def login():
# 判断当前用户是否验证,如果通过验证,返回首页
if current_user.is_authenticated:
return redirect(url_for('main.home'))
# 创建一个表单实例
form = LoginForm()
if form.validate_on_submit():
# 根据表格里的数据进行查询,查询到返回user对象,否则返回none
user = User.query.filter_by(email=form.email.data).first()
# 判断用户存在或者密码正确
if not user:
flash("未注册用户")
return redirect(url_for('main.login'))
if not user.check_password(form.password.data):
flash("密码错误")
return redirect(url_for('main.login'))
# 登录成功保存是否记住密码状态
login_user(user,remember=form.remember_me.data)
flash("登录成功")
# 记录跳转至登录页的地址
next_page = request.args.get('next')
# 记录的地址不存在返回首页
if not next_page or url_parse(next_page).netloc !='':
next_page = url_for('main.home')
return redirect(next_page)
return render_template(
'login.html',
title='Login',
form=form,
year=datetime.now().year
)
模版引用登录状态
我们在模版里可以通过使用来进行一些未登录模版的渲染等。
{% if current_user.is_authenticated() %}
Hi {{ current_user.name }}!
{% endif %}